<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<style>
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote {
    margin: 0;
    padding: 0;
}
body {
    font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif;
    font-size: 13px;
    line-height: 18px;
    color: #737373;
    background-color: white;
    margin: 10px 13px 10px 13px;
}
table {
	margin: 10px 0 15px 0;
	border-collapse: collapse;
}
td,th {	
	border: 1px solid #ddd;
	padding: 3px 10px;
}
th {
	padding: 5px 10px;	
}

a {
    color: #0069d6;
}
a:hover {
    color: #0050a3;
    text-decoration: none;
}
a img {
    border: none;
}
p {
    margin-bottom: 9px;
}
h1,
h2,
h3,
h4,
h5,
h6 {
    color: #404040;
    line-height: 36px;
}
h1 {
    margin-bottom: 18px;
    font-size: 30px;
}
h2 {
    font-size: 24px;
}
h3 {
    font-size: 18px;
}
h4 {
    font-size: 16px;
}
h5 {
    font-size: 14px;
}
h6 {
    font-size: 13px;
}
hr {
    margin: 0 0 19px;
    border: 0;
    border-bottom: 1px solid #ccc;
}
blockquote {
    padding: 13px 13px 21px 15px;
    margin-bottom: 18px;
    font-family:georgia,serif;
    font-style: italic;
}
blockquote:before {
    content:"\201C";
    font-size:40px;
    margin-left:-10px;
    font-family:georgia,serif;
    color:#eee;
}
blockquote p {
    font-size: 14px;
    font-weight: 300;
    line-height: 18px;
    margin-bottom: 0;
    font-style: italic;
}
code, pre {
    font-family: Monaco, Andale Mono, Courier New, monospace;
}
code {
    background-color: #fee9cc;
    color: rgba(0, 0, 0, 0.75);
    padding: 1px 3px;
    font-size: 12px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;
}
pre {
    display: block;
    padding: 14px;
    margin: 0 0 18px;
    line-height: 16px;
    font-size: 11px;
    border: 1px solid #d9d9d9;
    white-space: pre-wrap;
    word-wrap: break-word;
}
pre code {
    background-color: #fff;
    color:#737373;
    font-size: 11px;
    padding: 0;
}
sup {
    font-size: 0.83em;
    vertical-align: super;
    line-height: 0;
}
* {
	-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
    body {
        width: 854px;
        margin:10px auto;
    }
}
@media print {
	body,code,pre code,h1,h2,h3,h4,h5,h6 {
		color: black;
	}
	table, pre {
		page-break-inside: avoid;
	}
}
</style>
<title>爱音乐s09e01 api文档v0.2</title>

</head>
<body>
<h1>爱音乐s09e01 api文档v0.2</h1>

<p>所有的通信都使用POST方法，请求和返回数据都为JSON格式</p>

<h2>授权部分</h2>

<p>测试环境域名为http://test.m.muzhibuluo.com</p>

<p>正式环境域名为http://m.muzhibuluo.com</p>

<p>请不要把host写死，设成一个全局变量，方便修改</p>

<h2>微信认证</h2>

<h3>登录</h3>

<h4>简要描述：</h4>

<p>登录微信</p>

<h4>请求URL：</h4>

<p>域名 + /auth/wechat/login</p>

<h4>请求方式：</h4>

<p>POST</p>

<h4>请求参数：</h4>

<table>
<thead>
<tr>
<th> 参数名        </th>
<th align="center"> 必选           </th>
<th align="center"> 说明  </th>
</tr>
</thead>
<tbody>
<tr>
<td> gamesRedirectUri      </td>
<td align="center"> 是      </td>
<td align="center">   授权后重定向的回调链接地址，urlencode </td>
</tr>
<tr>
<td> datetime      </td>
<td align="center"> 否 </td>
<td align="center"> 当前时间戳 </td>
</tr>
<tr>
<td> state      </td>
<td align="center"> 否 </td>
<td align="center"> 微信重定向透传参数 </td>
</tr>
</tbody>
</table>


<h4>返回参数说明</h4>

<p>用户未授权时返回</p>

<pre><code>{
  "result": "unauth",
  "url": "https://xxxxxxxx"   // 微信授权需要跳转的url
}
</code></pre>

<p>用户已授过权时返回</p>

<pre><code>{
  "result": "success",
  "mz_jwt": "xxxxxxxxxx"   // jwt token, 请求api服务器时携带
  "user" {
    openid: "C702A1E822C000015FA9528FD41B2130"
  }
}
</code></pre>

<p>请求失败返回事例</p>

<pre><code>{
  "result": "error",
  "errmsg": "gamesRedirectUri is null!"   // 错误信息
}
</code></pre>

<h4>备注</h4>

<hr />

<h3>微信JSSDK签名</h3>

<h4>简要描述：</h4>

<p>获取微信jssdk ticket</p>

<h4>请求URL：</h4>

<p>域名 + /auth/wechat/jssdk</p>

<h4>请求方式：</h4>

<p>POST</p>

<h4>请求参数：</h4>

<table>
<thead>
<tr>
<th> 参数名        </th>
<th align="center"> 必选           </th>
<th align="center"> 说明  </th>
</tr>
</thead>
<tbody>
<tr>
<td> originalUrl      </td>
<td align="center"> 是      </td>
<td align="center">  请求jssdk签名页面的url </td>
</tr>
<tr>
<td> datetime      </td>
<td align="center"> 否 </td>
<td align="center"> 当前时间戳 </td>
</tr>
</tbody>
</table>


<h4>返回参数说明</h4>

<p>成功时返回</p>

<pre><code>{
    "result": "success"
    "jssdk": {
        "appId": "wxd9d2aa3dfg275aa"
        "jsapi_ticket":"xxxxxxxxxxx"
        "nonceStr": "sd5uiyyy48mjwcd"
        "signature": "716b2a8c697ed78957b3eb05c890d659c13de95c"
        "timestamp": "1459331404"
        "url": "http://test.m.muzhibuluo.com/2016/q1/biz/uber_s23e01/startup.html"
        "result": "success"
    }
}
</code></pre>

<p>请求失败返回事例</p>

<pre><code>{
  "result": "error",
  "errmsg": "xxxxx"   // 错误信息
}
</code></pre>

<h4>备注</h4>

<hr />

<h2>匿名认证</h2>

<h3>登录</h3>

<h4>简要描述：</h4>

<p>匿名登录, 服务端生成一个openid作为标识返回</p>

<h4>请求URL：</h4>

<p>域名 + /auth/anonymous/login</p>

<h4>请求方式：</h4>

<p>POST</p>

<h4>请求参数：</h4>

<table>
<thead>
<tr>
<th> 参数名        </th>
<th align="center"> 必选           </th>
<th align="center"> 说明  </th>
</tr>
</thead>
<tbody>
<tr>
<td> gamesRedirectUri      </td>
<td align="center"> 是      </td>
<td align="center">   授权后重定向的回调链接地址，urlencode </td>
</tr>
<tr>
<td> datetime      </td>
<td align="center"> 否 </td>
<td align="center"> 当前时间戳 </td>
</tr>
</tbody>
</table>


<h4>返回参数说明</h4>

<p>返回</p>

<pre><code>{
  "result": "success",
  "mz_jwt": "xxxxxxxxxx"   // jwt token, 请求api服务器时携带
  "user" {
    openid: "C702A1E822C000015FA9528FD41B2130"  // 服务端生成的匿名
  }
}
</code></pre>

<h4>备注：</h4>

<p>若用户之前登录过微信或者qq，则返回微信或qq的openid</p>

<hr />

<h3>Demo 代码</h3>

<p>demo可以参照以前项目的代码</p>

<pre><code>var apiHost = 'http://test.api.muzhibuluo.com';
//var apiHost = 'http://api.m.muzhi.com';
var apiPrefix = apiHost+'/api/imusic_s08e01';

var mz_jwt='';
var ua = window.navigator.userAgent.toLowerCase();
var wxurl = '';
var IsWeixin;

if(ua.match(/MicroMessenger/i) == 'micromessenger'){ 
  IsWeixin = true;
  wxurl = '/auth/wechat/login';
}else{
  IsWeixin = false;
  wxurl = '/auth/anonymous/login';
}

Zepto.post(wxurl+'?gamesRedirectUri='+encodeURIComponent(location.href.split('#')[0]),function(res){
  console.log('location.href',location.href);
    if(res.result === 'error'){
        console.log('login error', res.errmsg);
        location.href = res.url;
    }else if(res.result === 'unauth'){
        console.log('login unauth', res.url);
        location.href = res.url;
    }else{
        console.log('logined', res);
        console.log('current wechat user', res.user);
        $$Client.nickname = res.user.nickname;
        mz_jwt = res.mz_jwt;
        $('#pageLoading').show();
        $(document).on('ajaxBeforeSend', function(e, xhr, options){
          xhr.setRequestHeader("Authorization","Bearer "+mz_jwt);
        })
        getJSSDK();
    }
})

function getJSSDK(){
  Zepto.post('/auth/wechat/jssdk?originalUrl='+encodeURIComponent(location.href.split('#')[0]), function(res){
      var jssdk = res.jssdk;
      wx.config({
          debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
          appId: jssdk.appId, // 必填，公众号的唯一标识
          timestamp: jssdk.timestamp, // 必填，生成签名的时间戳
          nonceStr: jssdk.nonceStr,   // 必填，生成签名的随机串
          signature: jssdk.signature, // 必填，签名，见附录1
          jsApiList: [
              'onMenuShareTimeline',
              'onMenuShareAppMessage',
              'onMenuShareQQ',
              'onMenuShareWeibo'
          ] // 必填，需要使用的JS接口列表，所有JS接口列表见附录2
      });

      // 其他初始化工作

  })
  Zepto.ajax({
    type: "POST",
    url: apiPrefix+"/init",
    cache: false,
    asyn: false,
    success: function(data){
        // 游戏开始
    }
  })
}
</code></pre>

<hr />

<h2>API部分</h2>

<p>测试环境 apiPrefix = 'http://test.api.muzhibuluo.com/api/imusic_s08e01'</p>

<p>线上环境 apiPrefix = 'http://api.muzhibuluo.com/api/imusic_s08e01'</p>

<p>每次请求api在头部带上授权时得到的token</p>

<pre><code>$(document).on('ajaxBeforeSend', function(e, xhr, options){
      xhr.setRequestHeader("Authorization","Bearer "+mz_jwt);
})
</code></pre>

<h3>初始化</h3>

<h4>url: apiPrefix + /init</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code></code></pre>

<h4>返回：</h4>

<pre><code>{

    "lotteryNum": int/可以抽奖的次数
}
</code></pre>

<h4>更多说明：</h4>

<hr />

<h3>抽奖</h3>

<h4>url: apiPrefix + /lottery</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<p>无</p>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "msg": string/错误信息,
    "lotteryNum": int/可以抽奖的次数,
    "ret": int/1表示中奖，0表示不中,
    "prize": {
        "prizeName": string/奖品名,
        "level": int/奖品等级,
        "code": string/优惠券码
    }
}
</code></pre>

<h4>更多说明：</h4>

<hr />

<h3>领取流量话费</h3>

<h4>url: apiPrefix + /getPrize</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code>{
    "prizeLevel": int/奖品等级,
    "phone": int/手机号码
    "code": string/验证码，如果需要
    "fromWechat": bool/是否来自微信

}
</code></pre>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "msg": string/错误信息,

}
</code></pre>

<h4>更多说明：</h4>

<hr />

<h3>领取音乐盒</h3>

<h4>url: apiPrefix + /getMusicBox</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code>{
    "phone": int/手机号码
    "code": string/验证码
    "fromWechat": bool/是否来自微信

}
</code></pre>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "msg": string/错误信息,

}
</code></pre>

<h4>更多说明：</h4>

<hr />

<h3>领取钻石会员</h3>

<h4>url: apiPrefix + /getMember</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code>{
    "phone": int/手机号码
    "code": string/验证码
    "fromWechat": bool/是否来自微信

}
</code></pre>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "msg": string/错误信息,

}
</code></pre>

<h4>更多说明：</h4>

<hr />

<h3>发送钻石会员验证码</h3>

<h4>url: apiPrefix + /memberRandomCode</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code>
{ 
    "phone": int/手机号
    "fromWechat": bool/是否来自微信

}
</code></pre>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "msg": string/错误信息,

}
</code></pre>

<h4>更多说明：</h4>

<hr />

<h3>发送音乐盒验证码</h3>

<h4>url: apiPrefix + /musicRandomCode</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code>
{ 
    "phone": int/手机号
    "fromWechat": bool/是否来自微信

}
</code></pre>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "msg": string/错误信息,

}
</code></pre>

<h4>更多说明：</h4>

<hr />

<h3>查询是否彩铃用户</h3>

<h4>url: apiPrefix + /iscrbtuser</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code>
{ 
    "phone": int/手机号

}
</code></pre>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "iscrbtuser": bool/是否彩铃用户,
    "msg": string/错误信息,

}
</code></pre>

<h4>更多说明：</h4>

<hr />

<h3>开通彩铃</h3>

<h4>url: apiPrefix + /openCrbt</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code>
{ 
    "phone": int/手机号
    "fromWechat": bool/是否来自微信
    "code": int/验证码

}
</code></pre>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "msg": string/错误信息,

}
</code></pre>

<h4>更多说明：</h4>

<p>验证码通过调用 /musicRandomCode 接口获取</p>

<hr />

<h3>查询音乐盒</h3>

<h4>url: apiPrefix + /songs</h4>

<h4>method: POST</h4>

<h4>参数：</h4>

<pre><code>
{
    "fromWechat": bool/是否来自微信
}
</code></pre>

<h4>返回：</h4>

<pre><code>{
    "succeess": bool/请求是否成功,
    "msg": string/错误信息,
    "data": [
        {
            "url": string/音乐url
            "resource_id":  int/资源id
            "song"    string/歌曲名
            "singer": string/歌手名
        }
    ]

}
</code></pre>

<h4>更多说明：</h4>

<hr />
</body>
</html>